package api

import (
	"bufio"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"reflect"
)

type LoggerInfo struct {
	Url        string `json:"url"`
	Method     string `json:"method"`
	ClientIP   string `json:"client_ip"`
	StatusCode string `json:"status_code"`
	Date       string `json:"date"`
}

type RequestLogger struct {
	format     string
	write2File bool
}

func NewRequestLogger(format string, write2File bool) *RequestLogger {
	formatString := ""
	if format == "text" {
		formatString += "text"
	} else if format == "json" {
		formatString += "json"
	} else {
		formatString += "text"
	}
	return &RequestLogger{
		format:     formatString,
		write2File: write2File,
	}
}

func (_this *RequestLogger) WriteLog(loggerInfo LoggerInfo) {
	if reflect.ValueOf(loggerInfo).Kind() != reflect.Struct {
		log.Fatal("LoggerInfo is invalid")
		return
	}
	loggerStirng := _formatLoggerInfo(loggerInfo, _this.format)
	if _this.write2File {
		_writeToFile(loggerStirng)
	}
	fmt.Println(loggerStirng)
}
func _writeToFile(loggerStirng string) {
	// f, error := os.Create("./log/request_info.log")
	// if error != nil {
	// 	log.Fatal(error)
	// 	return
	// }
	// l, error := f.WriteString(loggerStirng)
	// if error != nil {
	// 	log.Fatal(error)
	// 	f.Close()
	// 	return
	// }
	// fmt.Println(l, "log stirng written successfully")
	// error = f.Close()
	// if error != nil {
	// 	log.Fatal(error)
	// 	return
	// }
	file, err := os.OpenFile("./log/request_info.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		fmt.Println("获取文件句柄失败：", err)
		os.Exit(2)
	}
	defer file.Close()
	writer := bufio.NewWriter(file)
	writer.WriteString(loggerStirng)
	writer.Flush()

}
func _formatLoggerInfo(loggerInfo LoggerInfo, format string) string {
	if format == "text" {
		return _getLoggerText(loggerInfo)
	} else {
		return _getJsonLogger(loggerInfo)
	}
}

func _getJsonLogger(loggerInfo LoggerInfo) string {
	data, error := json.Marshal(loggerInfo)
	if error != nil {
		panic(error)
	}
	return string(data)
}
func _getLoggerText(loggerInfo interface{}) string {
	value := reflect.ValueOf(loggerInfo)
	kind := value.Kind()
	if kind != reflect.Struct {
		log.Fatal("invalid struct")
		return ""
	}
	loggerInfoString := ""
	loggerInfoTag := []string{"地址：", "方法：", "客户IP：", "状态码：", "当前时间："}
	size := value.NumField()
	for index := 0; index < size; index++ {
		value := value.Field(index)
		prop := value.Interface().(string)
		if prop != "" {
			loggerInfoString += loggerInfoTag[index] + prop + "\n"
		}

	}
	for i := 0; i < size*6; i++ {
		loggerInfoString += "="
	}
	loggerInfoString += "\n"
	return loggerInfoString
}
